package com.pangu.ui.browser;

import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.HeaderViewListAdapter;
import android.widget.ListView;

import com.pangu.AMApplication;
import com.pangu.ui.R;

/**
 * 内套了一个ListView列表项视图
 * <p/>
 * Created by cxlin
 */
public abstract class ListItemBrowser<A extends AMApplication> extends LoadableList<A> {

	// 始终始列表高度为列表中的项总长度一致
	private boolean fixHeight;

	public ListItemBrowser(Context context) {
		super(context);
	}

	public ListItemBrowser(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public ListItemBrowser(Context context, boolean fixHeight) {
		super(context);
		this.fixHeight = fixHeight;
	}

	@Override
	protected AdapterView createAdapterView() {
		ListView listView = null;
		if (fixHeight) {
			listView = new FixListView(getContext());
			setListViewParameters(listView);

		} else {
			listView = new ListView(getContext());
			setListViewParameters(listView);
		}

		// 添加头部
		addListHeader(listView);
		// 添加底部
		addListFooter(listView);

		return listView;
	}

	/**
	 * 设置默认的ListView的风格和参数，子类不要将其重新实现
	 * 
	 * @param listView
	 */
	protected void setListViewParameters(ListView listView) {
		listView.setVerticalFadingEdgeEnabled(true);
		listView.setBackgroundResource(android.R.color.white);
		listView.setDivider(getResources().getDrawable(R.drawable.mui__list_divider_bg));
		listView.setCacheColorHint(getResources().getColor(R.color.mui__transparent));
		// 将列表的selector设置为透明，状态由子项自己设置
		listView.setSelector(new ColorDrawable(getResources().getColor(R.color.mui__transparent)));
		listView.setFadingEdgeLength(0);
	}

	/**
	 * 添加List的头部标题
	 * 
	 * @param listView
	 */
	protected void addListHeader(ListView listView) {
		// 空实现，子类要头部自己复盖。
	}

	/**
	 * 移除列表头部
	 * 
	 * @param header
	 */
	public void removeListHeader(View header) {
		((ListView) adapterView).removeHeaderView(header);
	}

	/**
	 * 添加List的底部视图
	 * 
	 * @param listView
	 */
	protected void addListFooter(ListView listView) {
		// 空实现，子类要底部自己复盖。
	}

	/**
	 * 移除列表底部
	 * 
	 * @param footer
	 */
	public void removeListFooter(View footer) {
		((ListView) adapterView).removeFooterView(footer);
	}

	public boolean isFixHeight() {
		return fixHeight;
	}

	public void setFixHeight(boolean fixHeight) {
		this.fixHeight = fixHeight;
	}

	/**
	 * 此列表视图高度始终始为列表中的项总长度<br>
	 * 如果用于分页类别必须注意分页逻辑确保不会发生无效加载的现象。 <br>
	 */
	private class FixListView extends ListView {
		// 子项高度
		private int childHeight;

		public FixListView(Context context) {
			super(context);
			setFadingEdgeLength(0);
		}

		@Override
		public int getFirstVisiblePosition() {
			Rect rect = new Rect();
			getLocalVisibleRect(rect);
			int first = rect.top / (childHeight == 0 ? 1 : childHeight);
			return first < 0 ? 0 : first;
		}

		@Override
		public int getLastVisiblePosition() {
			Rect rect = new Rect();
			getLocalVisibleRect(rect);
			int last = rect.bottom / (childHeight == 0 ? 1 : childHeight);
			last = last < getCount() ? last : last - 1;
			return last < 0 ? 0 : last;
		}

		private void measureScrapChild(View child, int widthMeasureSpec) {
			LayoutParams p = (LayoutParams) child.getLayoutParams();
			if (p == null) {
				p = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 0);
				child.setLayoutParams(p);
			}

			int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec, 0, p.width);
			int lpHeight = p.height;
			int childHeightSpec;
			if (lpHeight > 0) {
				childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
			} else {
				childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
			}
			child.measure(childWidthSpec, childHeightSpec);
		}

		@Override
		protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
			int itemCount = 0, heightSize = 0;
			View itemView = null, headerView = null, footView = null;
			Adapter adapter = getAdapter();
			if (adapter instanceof HeaderViewListAdapter) {
				HeaderViewListAdapter headerAdapter = (HeaderViewListAdapter) adapter;
				itemCount = headerAdapter.getCount() - headerAdapter.getHeadersCount()
						- headerAdapter.getFootersCount();

				if (headerAdapter.getHeadersCount() > 0) {
					headerView = headerAdapter.getView(0, null, this);
				}

				if (headerAdapter.getFootersCount() > 0) {
					footView = headerAdapter.getView(headerAdapter.getCount() - 1, null, this);
				}

				if (itemCount > 0) {
					itemView = headerAdapter.getView(headerAdapter.getHeadersCount(), null, this);
				}

			} else if (adapter != null) {
				itemCount = adapter.getCount();
				if (itemCount > 0) {
					itemView = adapter.getView(0, null, this);
				}
			}

			// 设置为所有项总长
			if (itemView != null) {
				measureScrapChild(itemView, widthMeasureSpec);
				// 分隔线
				int dividerHeight = getDividerHeight();
				childHeight = itemView.getMeasuredHeight();
				heightSize = childHeight * itemCount + dividerHeight * (itemCount - 1);
				if (headerView != null) {
					// 某些rom headerview会没有layoutparams，在measure的时候会导致奔溃
					if (headerView.getLayoutParams() == null) {
						headerView.setLayoutParams(getDefaultLayoutParams());
					}
					headerView.measure(widthMeasureSpec, heightMeasureSpec);
					heightSize += headerView.getMeasuredHeight() + dividerHeight;
				}

				if (footView != null) {
					// 某些rom footView会没有layoutparams，在measure的时候会导致奔溃
					if (footView.getLayoutParams() == null) {
						footView.setLayoutParams(getDefaultLayoutParams());
					}
					footView.measure(widthMeasureSpec, heightMeasureSpec);
					heightSize += footView.getMeasuredHeight() + dividerHeight;
				}
			}

			if (heightSize > 0) {
				super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(heightSize + getPaddingTop()
						+ getPaddingBottom(), MeasureSpec.EXACTLY));

			} else {
				super.onMeasure(widthMeasureSpec, heightMeasureSpec);
			}
		}

		/**
		 * 获取默认layoutparams
		 * 
		 * @return
		 */
		private LayoutParams getDefaultLayoutParams() {
			return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
		}

	}

}
